/*
 * OpenSceneGraph + Qt + Offscreen rendering example.
 * Copyright (C) 2011  Gonzalo Exequiel Pedone
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with This program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Email   : hipersayan DOT x AT gmail DOT com
 * Web-Site: http://hipersayanx.blogspot.com/
 */

#include <osgDB/Registry>
#include "../include/qosgwidget.h"

QOSGWidget::QOSGWidget(QWidget *parent): QGLWidget(parent)
{
    // Creamos un nuevo visor para mostrar la escena mediante OSG.
    viewer = new osgViewer::Viewer;

    // Creamos una matriz de transformacion que luego usaremos para rotar el modelo 3D.
    // Esta, actuará como nodo raiz.
    transformation = new osg::MatrixTransform;

    //const osgDB::Options* pOpt = osgDB::Registry::instance()->getOptions();

    // Cargamos el modelo 3D.
    // Este, actuará como Geodo (Nodo Geometrico o Nodo Hoja).
    std::string strFile = "data/cow.osg";
    loadedModel = osgDB::readNodeFile(strFile);

    // Establecemos al modelo 3D como descendiente de la transformación.
    transformation->addChild(loadedModel.get());

    // Angulo de rotación de 0°.
    cow_rot = 0;
}

void QOSGWidget::initializeGL()
{
    // Asociamos el contexto OpenGL creado por el QGLWidget a OSG
    // y configuramos el viewport.
    window = viewer->setUpViewerAsEmbeddedInWindow(0, 0, width(), height());

    // Asociamos algun método de manipulación de camara para OSG.
    viewer->setCameraManipulator(new osgGA::TrackballManipulator);
}

void QOSGWidget::resizeGL(int width, int height)
{
    if (window.valid())
    {
        // Ajustamos las dimenciones de la escena OSG si el widget cambia de tamaño.
        window->resized(window->getTraits()->x, window->getTraits()->y, width, height);
        window->getEventQueue()->windowResize(window->getTraits()->x, window->getTraits()->y, width, height);
    }
}

void QOSGWidget::paintGL()
{
    // Establecemos una matriz de rotacion para girar el modelo 3D
    // al rededor del eje vertical (eje z).
    transformation->setMatrix(osg::Matrix::rotate(cow_rot, 0, 0, 1));

    // Colocamos el nodo raiz adentro de la escena.
    viewer->setSceneData(transformation.get());

    // Aumentamos el angulo de rotación.
    cow_rot += 0.1;

    // Renderizamos el frame.
    if (viewer.valid())
        viewer->frame();
}
